package stringset

import (
	"sort"
	// "fmt"
	"strings"
)

const testVersion = 4

type Set struct {
	content []string
}

func New() Set {
	return Set{}
}

func NewFromSlice(inputs []string) Set {
	m := make(map[string]int)
	for i := 0; i < len(inputs); i++ {
		m[inputs[i]] = 1
	}

	var t []string
	for k, _ := range m {
		t = append(t, k)
	}

	return Set{t}
}

func (stringSet Set) String() string {
	temp := make([]string, len(stringSet.content))
	for i := 0; i < len(temp); i++ {
		temp[i] = `"` + stringSet.content[i] + `"`
	}
	return "{" + strings.Join(temp, ", ") + "}"
}

func (stringSet Set) IsEmpty() bool {
	return len(stringSet.content) == 0
}

func (stringSet Set) Has(ele string) bool {
	for i := 0; i < len(stringSet.content); i++ {
		if stringSet.content[i] == ele {
			return true
		}
	}

	return false
}

func Subset(s1, s2 Set) bool {
	if len(s1.content) == 0 {
		return true
	}

	want := len(s1.content)
	for i := 0; i < len(s1.content); i++ {
		for j := 0; j < len(s2.content); j++ {
			if s2.content[j] == s1.content[i] {
				want--
			}
		}
	}

	return want == 0
}

func Disjoint(s1, s2 Set) bool {
	if len(s1.content) == 0 || len(s2.content) == 0 {
		return true
	}

	want := len(s1.content)
	for i := 0; i < len(s1.content); i++ {
		for j := 0; j < len(s2.content); j++ {
			if s2.content[j] == s1.content[i] {
				want--
			}
		}
	}

	return want == len(s1.content)
}

func Equal(s1, s2 Set) bool {
	sort.Strings(s1.content)
	sort.Strings(s2.content)
	return s1.String() == s2.String()
}

func (stringSet *Set) Add(ele string) {
	if stringSet.IsEmpty() {
		stringSet.content = []string{ele}
	} else {
		isNotIn := true
		for i := 0; i < len(stringSet.content); i++ {
			if stringSet.content[i] == ele {
				isNotIn = false
			}
		}
		if isNotIn {
			stringSet.content = append(stringSet.content, ele)
		}
	}
}

func Intersection(s1, s2 Set) Set {
	var both []string
	for i := 0; i < len(s1.content); i++ {
		for j := 0; j < len(s2.content); j++ {
			if s2.content[j] == s1.content[i] {
				both = append(both, s2.content[j])
			}
		}
	}

	return Set{both}
}

func Difference(s1, s2 Set) Set {
	var both []string
	for i := 0; i < len(s1.content); i++ {
		notEqual := true
		for j := 0; j < len(s2.content); j++ {
			if s2.content[j] == s1.content[i] {
				notEqual = false
			}
		}
		if notEqual {
			both = append(both, s1.content[i])
		}
	}

	return Set{both}
}

func Union(s1, s2 Set) Set {
	s := Set{s1.content}

	for i := 0; i < len(s2.content); i++ {
		s.Add(s2.content[i])
	}

	return s
}
